/*
 *    This file is part of SSHTunneler.
 *
 *    Copyright 2009 Jean-Sebastien Gelinas <calestar@gmail.com>
 *
 *    SSHTunneler is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    SSHTunneler is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with SSHTunneler.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package sshtunneler.client;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import sshtunneler.client.data.Config;
import sshtunneler.client.data.TunnelerServerContainer;
import sshtunneler.client.data.TunnelerServerTunnelFile;
import sshtunneler.client.gui.SSHTunnelerView;
import sshtunneler.client.ssh.SSHConnection;
import sshtunneler.client.ssh.SSHConnectionContainer;
import sshtunneler.client.tray.SysTrayManager;
import sshtunneler.library.Server;
import sshtunneler.tools.ToolsManager;

public class SSHTunnelerApp implements ActionListener {

	SSHTunnelerView view;
	boolean view_shown;
	PopupMenu popup = new PopupMenu();
	MenuItem menu_open = new MenuItem("Open");
	MenuItem menu_configure = new MenuItem("Configure");
	MenuItem menu_connect_all = new MenuItem("Connect to all");
	MenuItem menu_quit = new MenuItem("Quit");

	public SSHTunnelerView getMainFrame() {
		return this.view;
	}

	public void show(JDialog diag) {
		diag.setVisible(true);
	}

	public void show(JFrame f) {
		f.setVisible(true);
	}

	public void hide(JFrame f) {
		f.setVisible(false);
	}

	protected void toggle_view() {
		// We don't want to hide if we don't have SysTray !
		if (!SysTrayManager.inst.installed()) {
			return;
		}
		if (this.view_shown) {
			this.view_shown = false;
			this.menu_open.setLabel("Open");
			this.hide(this.view);
		} else {
			this.view_shown = true;
			this.menu_open.setLabel("Close");
			this.show(this.view);
			this.view.requestFocus();
			this.view.toFront();
		}
	}

	public void quit() {
		System.exit(0);
	}

	protected void startup() {
		ToolsManager.init(TunnelerServerContainer.inst, "tools");

		this.view = new SSHTunnelerView();
		this.show(this.view);
		this.view_shown = true;

		Config.inst.auto_load();
		TunnelerServerTunnelFile.inst.auto_load();
		this.view.refresh_tree();
		if (SysTrayManager.inst.can_use_systray) {
			try {
				Image image = new ImageIcon(ImageIO.read(this.getClass()
						.getClassLoader().getResourceAsStream("tray.png")))
						.getImage();
				this.menu_open.addActionListener(this);
				this.menu_connect_all.addActionListener(this);
				this.menu_configure.addActionListener(this);
				this.menu_quit.addActionListener(this);

				this.popup.add(this.menu_open);
				this.popup.addSeparator();
				this.popup.add(this.menu_connect_all);
				this.popup.add(this.menu_configure);
				this.popup.addSeparator();
				this.popup.add(ToolsManager.inst.get_tray_tools_menu(this));
				this.popup.addSeparator();
				this.popup.add(this.menu_quit);

				SysTrayManager.inst.install_icon(new MouseListener() {

					public void mouseClicked(MouseEvent e) {
						if (e.getButton() == MouseEvent.BUTTON1) { // Left click
							SSHTunnelerApp.this.toggle_view();
						}
					}

					public void mousePressed(MouseEvent e) {
						/* Ignore */
					}

					public void mouseReleased(MouseEvent e) {
						/* Ignore */
					}

					public void mouseEntered(MouseEvent e) {
						/* Ignore */
					}

					public void mouseExited(MouseEvent e) {
						/* Ignore */
					}
				}, null, this.popup, "SSHTunneler", image);
				if (Config.start_minimized && SysTrayManager.inst.installed()) {
					this.view_shown = false;
					this.hide(this.view);
				}
			} catch (AWTException ex) {
				Logger.getLogger(SSHTunnelerApp.class.getName()).log(
						Level.SEVERE, null, ex);
			} catch (IOException ex) {
				Logger.getLogger(SSHTunnelerApp.class.getName()).log(
						Level.SEVERE, null, ex);
			}
		}
		if (!SysTrayManager.inst.can_use_systray
				|| !SysTrayManager.inst.installed()) {
			JOptionPane
					.showMessageDialog(
							null,
							"You are using Java version "
									+ System.getProperty("java.version")
									+ ". Java version 1.6+ is needed to use all the functionnalities of this program.");
		}
		if (Config.connect_to_all_on_start) {
			this.connect_to_all();
		}
	}

	static SSHTunnelerApp app;

	public static SSHTunnelerApp getApplication() {
		return app;
	}

	public static void main(String[] args) {
		app = new SSHTunnelerApp();
		app.startup();
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(this.menu_open)) {
			this.toggle_view();
		} else if (e.getSource().equals(this.menu_quit)) {
			this.quit();
		} else if (e.getSource().equals(this.menu_configure)) {
			this.view.show_config();
		} else if (e.getSource().equals(this.menu_connect_all)) {
			this.connect_to_all();
		} else {
			ToolsManager.inst.process_event(e.getSource());
		}
	}

	private void connect_to_all() {
		for (Server server : TunnelerServerContainer.inst.getServers()) {
			SSHConnection conn = SSHConnectionContainer.inst.connectTo(server);
			if (conn != null) {
				conn.establishAllTunnels();
			}
		}
	}
}
